//src/core/cloudApi.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { log } from 'console';
const request = require('request');

interface CloudUser {
  id: string;
  username: string;
}

@Injectable()
export class CloudApiService {
  private readonly logger = new Logger(CloudApiService.name);

  constructor(private readonly config: ConfigService) {}

  async validateToken(token: string): Promise<CloudUser | null> {
    const code= await this.fetchCode();
    console.log('token',token);
    
    console.log('code',code);
    if(!code) {
      this.logger.error('Failed to fetch code');
      return null;
    }
    const accessToken = await this.fetchAccessToken(code);
    console.log('accessToken',accessToken);
    
    if(!accessToken) {
      this.logger.error('Failed to fetch access token');
      return null;
    }

    
    
    return this.getUserInfo(accessToken,token);
  }
  private async getUserInfo(accessToken: string,token: string): Promise<CloudUser | null> {
    const userInfoUrl = `https://cloud.minapp.com/oserve/v2.4/table/user/record/${token}`;
    const options = {
      uri: userInfoUrl,
      method: 'GET',
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
      json: true,
    };
  
    return new Promise((resolve) => {
      request(options, (error, response, body) => {
        if (error || response.statusCode !== 200) {
          this.logger.error(`Failed to get user info: ${error?.message || body}`);
          resolve(null);
        } else {
          // Assuming body.objects contains the filtered result
          const user = body;
          resolve(user ? { id: user.id, username: user.username } : null);
        }
      });
    });
  }
  // 获取 Code
 async fetchCode(): Promise<string | null> {
  const authUrl = "https://cloud.minapp.com/api/oauth2/hydrogen/openapi/authorize/";
  const clientId = this.config.get<string>('CLOUD_CLIENT_ID');
  const clientSecret = this.config.get<string>('CLOUD_CLIENT_SECRET');

  const options = {
    url: authUrl,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    json: {
      client_id: clientId,
      client_secret: clientSecret,
    },
    jar: true, // 启用Cookie存储
    followAllRedirects: true, // 允许重定向
  };

  return new Promise((resolve) => {
    request(options, (error, response, body) => {
      if (error || response.statusCode !== 200) {
        this.logger.error(`Failed to fetch code: ${error?.message || JSON.stringify(body)}`);
        resolve(null);
      } else {
        resolve(body.code);
      }
    });
  });
 }
 
 async fetchAccessToken(code: string): Promise<string | null> {
  const tokenUrl = "https://cloud.minapp.com/api/oauth2/access_token/";
  const clientId = this.config.get<string>('CLOUD_CLIENT_ID');
  const clientSecret = this.config.get<string>('CLOUD_CLIENT_SECRET');

  const options = {
    url: tokenUrl,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    json: {
      client_id: clientId,
      client_secret: clientSecret,
      grant_type: 'authorization_code',
      code: code,
    },
  };

  return new Promise((resolve) => {
    request(options, (error, response, body) => {
      if (error || response.statusCode !== 200) {
        this.logger.error(`Failed to fetch access token: ${error?.message || JSON.stringify(body)}`);
        resolve(null);
      } else {
        resolve(body.access_token);
      }
    });
  });
 }

  // 刷新 Access Token
  async refreshToken(refreshToken: string): Promise<string | null> {
    const tokenUrl = "https://cloud.minapp.com/api/oauth2/access_token/";
    const clientId = this.config.get<string>('CLOUD_CLIENT_ID');
    const clientSecret = this.config.get<string>('CLOUD_CLIENT_SECRET');

    if (!clientId || !clientSecret || !refreshToken) {
      this.logger.error('Configuration error: missing CLOUD_CLIENT_ID, CLOUD_CLIENT_SECRET or refresh token');
      return null;
    }

    const options = {
      uri: tokenUrl,
      method: 'POST',
      json: {
        client_id: clientId,
        client_secret: clientSecret,
        grant_type: 'refresh_token',
        refresh_token: refreshToken,
      },
    };

    return new Promise((resolve, reject) => {
      request(options, (error, response, body) => {
        if (error) {
          this.logger.error(`Error refreshing access token: ${error.message}`);
          return resolve(null);
        }
        if (response.statusCode === 200) {
          resolve(body.access_token);
        } else {
          this.logger.error(`Failed to refresh access token: ${JSON.stringify(body)}`);
          resolve(null);
        }
      });
    });
  }
}